package com.zbkj.crmeb.order;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.annotation.Resource;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zbkj.crmeb.enums.*;
import com.zbkj.crmeb.order.channel.*;
import com.zbkj.crmeb.store.dao.StoreOrderInfoDao;
import com.zbkj.crmeb.store.model.StoreOrderInfo;
import com.zbkj.crmeb.store.service.*;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.constants.Constants;
import com.crmeb.core.common.CommonResult;
import com.crmeb.core.exception.CrmebException;
import com.crmeb.core.exception.ExceptionCodeEnum;
import com.github.pagehelper.util.StringUtil;
import com.zbkj.crmeb.chant.service.IChannelMerchantService;
import com.zbkj.crmeb.store.dao.PurchaseGoodsDao;
import com.zbkj.crmeb.store.dao.PurchaseOrderDao;
import com.zbkj.crmeb.store.model.PurchaseGoods;
import com.zbkj.crmeb.store.model.PurchaseOrder;
import com.zbkj.crmeb.store.model.StoreOrder;
import com.zbkj.crmeb.store.service.impl.KaiCangStoreOrderServiceImpl;
import com.zbkj.crmeb.store.vo.StoreOrderInfoVo;

import lombok.extern.slf4j.Slf4j;

/**
 * @generator: IntelliJ IDEA
 * @description: 拆单工厂类
 * @project:
 * @date: 2021年03月14日 17时04分
 */
@Slf4j
@Service
public class StoreOrderFactory {
    @Autowired
    private BuyerStoreOrderServiceImpl buyerStoreOrderService;
    @Autowired
    private EuropeStoreOrderServiceImpl europeStoreOrderService;
    @Autowired
    private TmallStoreOrderServiceImpl tmallStoreOrderService;
    @Autowired
    private XiYangYangStoreOrderServiceImpl xiYangYangStoreOrderService;
    @Autowired
    private ViettiStoreOrderServiceImpl viettiStoreOrderService;
    @Autowired
    private EfasionStoreOrderServiceImpl efasionStoreOrderService;
    @Autowired
    private LeamStoreOrderServiceImpl leamStoreOrderService;
    @Autowired
    private JkyStoreOrderServiceImpl jkyStoreOrderService;
    @Autowired
    private GbStoreOrderServiceImpl gbStoreOrderService;
    @Autowired
    private ImStoreOrderServiceImpl imStoreOrderService;
    @Autowired
    private CarottaStoreOrderServiceImpl carottaStoreOrderService;
    @Autowired
    private LavitaStoreOrderServiceImpl lavitaStoreOrderService;
    @Autowired
    private BellettiniStoreOrderServiceImpl bellettiniStoreOrderService;
    @Autowired
    private OrangeStoreOrderServiceImpl orangeStoreOrderService;
    @Autowired
    private UnibuyStoreOrderServiceImpl unibuyStoreOrderService;
    @Autowired
    private CrisStoreOrderServiceImpl crisStoreOrderService;
    @Autowired
    private LiChengStoreOrderServiceImpl liChengStoreOrderServiceImpl;
    @Autowired
    private EasyStoreOrderServiceImpl easyStoreOrderService;

    @Resource
    private PurchaseOrderDao purchaseOrderDao;
    @Resource
    private PurchaseGoodsDao purchaseGoodsDao;
    @Resource
    private StoreOrderStatusService storeOrderStatusService;
    @Autowired
    private StoreOrderInfoService storeOrderInfoService;
    @Autowired
    private StoreProductService storeProductService;
    @Autowired
    private StoreProductAttrValueService storeProductAttrValueService;
    @Autowired
    private IChannelMerchantService channelMerchantService;

    @Autowired
    private PurchaseGoodsService purchaseGoodsService;

    @Autowired
    private StoreOrderService storeOrderService;

    @Autowired
    private DaigoStoreOrderServiceImpl daigoStoreOrderService;

    @Resource
    private StoreOrderInfoDao dao;

    public AbstractStoreOrderService getStoreOrderService(BarCodeEnum barCode) {
        switch (barCode) {
//        //自建商品
//        case INSIDE_01:
//            return insideStoreOrderService;
            case BUYER:
                return buyerStoreOrderService;
            case EUROPE:
                return europeStoreOrderService;
            case TMALL:
                return tmallStoreOrderService;
            case IM:
                return imStoreOrderService;
            case XYY:
                return xiYangYangStoreOrderService;
            case VIETTI:
                return viettiStoreOrderService;
            case LEAM:
                return leamStoreOrderService;
            case JKY:
                return jkyStoreOrderService;
            case GB:
                return gbStoreOrderService;
            case CAROTTA:
                return carottaStoreOrderService;
            case LAVITA:
                return lavitaStoreOrderService;
            case BELLETTINI:
                return bellettiniStoreOrderService;
            case ORANGE:
                return orangeStoreOrderService;
            case UNIBUY:
                return unibuyStoreOrderService;
            case UNIBUY1:
                return unibuyStoreOrderService;
            case CRIS:
                return crisStoreOrderService;
            case LICHENG:
                return liChengStoreOrderServiceImpl;
            case EFASION:
                return efasionStoreOrderService;
            case DAIGO:
                return daigoStoreOrderService;
            case EASY:
            case CROSSEASY:
                return easyStoreOrderService;
            default:
                //内部推送
                return null;
//            throw new UnsupportedOperationException("不支持的code:" + barCode.getCode());
        }
    }

    public void pushOrder(StoreOrder storeOrder, BarCodeEnum barCode, Boolean isAuto) {
        // TODO didiok
        List<StoreOrderInfoVo> orderInfoVos = separateOrder(storeOrder, barCode, isAuto);
        if (CollectionUtils.isNotEmpty(orderInfoVos)) {
            this.getStoreOrderService(barCode).addChannelOrder(storeOrder, orderInfoVos);
        }
    }

    private List<StoreOrderInfoVo> separateOrder(StoreOrder storeOrder, BarCodeEnum barCode, Boolean isAuto) {
//        List<StoreOrderInfoVo> orderInfoVoList = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId());
        List<StoreOrderInfoVo> orderInfoVoList = storeOrderInfoService.getOrderListByOrderIdTwo(storeOrder.getId());
        List<StoreOrderInfoVo> result = new ArrayList<StoreOrderInfoVo>();
        for (StoreOrderInfoVo info : orderInfoVoList) {
            if (null == info.getInfo().getCostPrice() || null == info.getInfo().getTruePrice() || info.getInfo().getCostPrice().compareTo(info.getInfo().getTruePrice()) > 0) {
                continue;
            }
            String sourceBarCode = info.getInfo().getProductInfo().getBarCode();
            int tempId = info.getInfo().getProductInfo().getTempId();
            if (sourceBarCode.startsWith(barCode.getCode().toString())) {
                // 过滤欧洲订单取消推送
                if (BarCodeEnum.BUYER == barCode && StockAreaTempEnum.EUR.getTempId() == tempId && isAuto) {
                    continue;
                }
                // 过滤诚品订单非8f与够够商户, 已在其他地方处理
                if ((18 == storeOrder.getMerId() || 30 == storeOrder.getMerId() || 45 == storeOrder.getMerId() || 47 == storeOrder.getMerId()) && sourceBarCode.startsWith(BarCodeEnum.JKY.getCode().toString())) {
                    continue;
                }
                result.add(info);
            }
        }
        return result;
    }

    public void cancelOrder(StoreOrder storeOrder) {
        List<StoreOrderInfoVo> orderInfoVos = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId());
        if (null != orderInfoVos && orderInfoVos.size() > 0) {
            for (StoreOrderInfoVo info : orderInfoVos) {
                String sourceBarCode = info.getInfo().getProductInfo().getBarCode();
                //天猫订单 取消主订单
                if (sourceBarCode.startsWith(BarCodeEnum.BUYER.getCode().toString())) {
                    this.getStoreOrderService(BarCodeEnum.BUYER).cancelChannelOrder(storeOrder, orderInfoVos);
                } else if (sourceBarCode.startsWith(BarCodeEnum.EUROPE.getCode().toString())) {
                    this.getStoreOrderService(BarCodeEnum.EUROPE).cancelChannelOrder(storeOrder, null);
                } else if (sourceBarCode.startsWith(BarCodeEnum.IM.getCode().toString())) {
                    this.getStoreOrderService(BarCodeEnum.IM).cancelChannelOrder(storeOrder, null);
                } else if (sourceBarCode.startsWith(BarCodeEnum.XYY.getCode().toString())) {
                    this.getStoreOrderService(BarCodeEnum.XYY).cancelChannelOrder(storeOrder, null);
                }
            }
        }
    }

    public CommonResult<Object> orderInfo(String channelOrderSn, Integer channelType) {
        if (null == channelType) {
            throw new CrmebException("渠道类型异常");
        }
        if (ProductTypeEnum.IM.getCode().equals(channelType)) {
            return imStoreOrderService.getOrderInfo(channelOrderSn);
        }
        return CommonResult.failed(ExceptionCodeEnum.FAILED, "该供应商暂无订单详情");
    }

    public CommonResult<Object> getOrderLogisticsInfo(String channelOrderSn, Integer channelType) {
        if (null == channelType) {
            throw new CrmebException("渠道类型异常");
        }
        if (ProductTypeEnum.IM.getCode().equals(channelType)) {
            return imStoreOrderService.getOrderLogisticsInfo(channelOrderSn);
        }
        return CommonResult.failed(ExceptionCodeEnum.FAILED, "该供应商暂无订单物流详情");
    }

    /**
     * 生成采购单
     *
     * @author daigb
     * @date: 2022-01-14 13:51
     */
    public void insertPurchaseOrder(StoreOrder storeOrder, Boolean status, Integer channelType) {
        // 只能存在一张采购单
        int count = purchaseOrderDao.selectCount(Wrappers.<PurchaseOrder>lambdaQuery()
                .eq(PurchaseOrder::getStoreOrderId, storeOrder.getOrderId())
        );
        if (count > 0) {
            return;
        }

        PurchaseOrder order = new PurchaseOrder();
        BeanUtils.copyProperties(storeOrder, order);
        order.setGoodsAmount(storeOrder.getPayPrice());
        order.setStoreOrderId(storeOrder.getOrderId());
        order.setChannelType(channelType);
        order.setCreateTime(new Date());
        order.setAddTime(new Date());
        order.setCreateTime(new Date());
//        order.setChannelOrderSn(channelOrderSn);
        if (status) {
            order.setStatus(1);
        } else {
            order.setStatus(2);
        }
        purchaseOrderDao.insert(order);
    }

    /**
     * 生成采购商品
     *
     * @author daigb
     * @date: 2022-01-14 13:51
     */
    public void insertPurchaseGoods(StoreOrderInfoVo orderInfo, StoreOrder storeOrder, Boolean status, String msg, String sn) {
        PurchaseGoods goods = new PurchaseGoods();
        String userName = orderInfo.getInfo().getProductInfo().getUserName();

        goods.setCreateTime(new Date());
        goods.setStoreOrderId(storeOrder.getOrderId());
        goods.setStoreOrderInfoId(orderInfo.getId());
        goods.setPushStoreOrderId(storeOrder.getPushOrderNo());
        goods.setChannelOrderSn(StringUtils.isNotBlank(sn) ? sn : storeOrder.getPushOrderNo());
        goods.setChannelType(orderInfo.getInfo().getProductInfo().getIsEurope());
        goods.setSkuId(orderInfo.getInfo().getProductInfo().getAttrInfo().getSourceSkuId());
        //推送价格
        goods.setGoodsPrice(orderInfo.getInfo().getProductInfo().getAttrInfo().getSourceCost());
        goods.setGoodsNumber(orderInfo.getInfo().getCartNum() + "");
        goods.setGoodsAttr(orderInfo.getInfo().getProductInfo().getAttrInfo().getSuk());
        goods.setGoodsImg(orderInfo.getInfo().getProductInfo().getImage());
        goods.setGoodsName(orderInfo.getInfo().getProductInfo().getStoreName());
        goods.setGoodsCateId(orderInfo.getInfo().getProductInfo().getCateId());
        goods.setGoodsBrand(orderInfo.getInfo().getProductInfo().getBrandName());
        goods.setGoodsSupplier(orderInfo.getInfo().getProductInfo().getSupplierName());
        goods.setGoodsId(orderInfo.getInfo().getProductInfo().getId());
        goods.setGoodKeyword(orderInfo.getInfo().getProductInfo().getKeyword());

        goods.setGoodsTempId(orderInfo.getInfo().getProductInfo().getTempId());
        goods.setGoodsOtPrice(orderInfo.getInfo().getProductInfo().getAttrInfo().getOtPrice());
        goods.setUserName(StringUtils.isEmpty(userName) ? "系统自动推送" : userName);
        goods.setPushType(StringUtils.isEmpty(userName) ? 0 : 1);
        goods.setIp(orderInfo.getInfo().getProductInfo().getIp());
        goods.setPushStatus(status ? "1" : "0");
        goods.setPushMsg(msg);
        goods.setExchangeRate(orderInfo.getExchangeRate());
        goods.setStatus(status ? Constants.ORDER_STATUS_H5_CONFIRM : Constants.ORDER_STATUS_H5_UNPAID);
        goods.setCommodityType(orderInfo.getInfo().getProductInfo().getCommodityType());
        purchaseGoodsDao.insert(goods);
        try {
            StringBuilder logContent = new StringBuilder();
            logContent.append(StringUtils.isEmpty(userName) ? "系统自动推送" : "用户 " + userName + " 推送");
            logContent.append(status ? "成功！" : "失败！");
            storeOrderStatusService.createLog(storeOrder.getId(), storeOrder.getOrderId(), Constants.ORDER_LOG_PUSH_RESULT, logContent.toString());
        }catch (Exception e){
            log.error("日志记录异常：{}", e);
        }
        //推送成功 ，进入供应商财务逻辑
        if (status) {
            channelMerchantService.purchaseSupplierGood(goods, orderInfo);
        }
        // 记录手动推送日志
        if (!StringUtils.isEmpty(userName)) {
            StringBuilder sb = new StringBuilder();
            sb.append(userName);
            sb.append("推送订单商品: ");
            sb.append(orderInfo.getInfo().getProductInfo().getStoreName());
            sb.append(" ");
            sb.append(msg);
            storeOrderStatusService.createLog(storeOrder.getId(), storeOrder.getOrderId(), Constants.ORDER_STATUS_CACHE_PUSH_ORDER, sb.toString());
        }
        if (9 == storeOrder.getSource() && status && BooleanUtils.isFalse(orderInfo.getCheckStock())) {
            // 减库存
            log.info("--------------- 手动推送商品id: {},sourceSkuId:{}, 扣除库存: {} ---------------", orderInfo.getProductId(), orderInfo.getInfo().getProductInfo().getAttrInfo().getSourceSkuId(), orderInfo.getInfo().getCartNum());
            storeProductService.subProductStock(orderInfo.getInfo().getProductInfo().getId(), orderInfo.getInfo().getCartNum());
            // 减AttValue库存
            storeProductAttrValueService.subProductStock(orderInfo.getInfo().getProductInfo().getId(), orderInfo.getInfo().getProductInfo().getAttrInfo().getSourceSkuId(), orderInfo.getInfo().getCartNum());
        }
    }

    public void insertPurchaseGoods(List<StoreOrderInfoVo> orderInfoVoList, StoreOrder storeOrder, Boolean status, String msg, String sn, Boolean isJkyProduct) {
        PurchaseGoods goods = new PurchaseGoods();
        orderInfoVoList.stream().forEach(o -> {
            String userName = o.getInfo().getProductInfo().getUserName();
            goods.setCreateTime(new Date());
            goods.setStoreOrderId(storeOrder.getOrderId());
            goods.setStoreOrderInfoId(o.getId());
            goods.setPushStoreOrderId(storeOrder.getPushOrderNo());
            goods.setChannelOrderSn(StringUtils.isNotBlank(sn) ? sn : storeOrder.getPushOrderNo());
            goods.setChannelType(o.getInfo().getProductInfo().getIsEurope());
            goods.setSkuId(o.getInfo().getProductInfo().getAttrInfo().getSourceSkuId());
            goods.setGoodsPrice(o.getInfo().getProductInfo().getAttrInfo().getPrice());
            goods.setGoodsNumber(o.getInfo().getCartNum() + "");
            goods.setGoodsAttr(o.getInfo().getProductInfo().getAttrInfo().getSuk());
            goods.setGoodsImg(o.getInfo().getProductInfo().getAttrInfo().getImage());
            goods.setGoodsCateId(o.getInfo().getProductInfo().getCateId());
            goods.setGoodsName(o.getInfo().getProductInfo().getStoreName());
            goods.setGoodsBrand(o.getInfo().getProductInfo().getBrandName());
            goods.setGoodsSupplier(o.getInfo().getProductInfo().getSupplierName());
            goods.setGoodsTempId(o.getInfo().getProductInfo().getTempId());
            goods.setGoodsId(o.getInfo().getProductInfo().getId());
            goods.setGoodKeyword(o.getInfo().getProductInfo().getKeyword());
            goods.setGoodsOtPrice(o.getInfo().getProductInfo().getAttrInfo().getOtPrice());
            int pushType = 0;
            String pushName = "系统自动推送";
            if (StringUtil.isNotEmpty(userName) && !isJkyProduct) {
                pushType = 1;
                pushName = userName;
            } else if (isJkyProduct) {
                pushType = 2;
                pushName = "吉客云指定推送";
            }
            goods.setUserName(pushName);
            goods.setPushType(pushType);
            goods.setIp(o.getInfo().getProductInfo().getIp());
            goods.setPushStatus(status ? "1" : "0");
            goods.setPushMsg(msg);
            goods.setExchangeRate(o.getExchangeRate());
            goods.setStatus(status ? Constants.ORDER_STATUS_H5_CONFIRM : Constants.ORDER_STATUS_H5_UNPAID);
            goods.setCommodityType(o.getInfo().getProductInfo().getCommodityType());
            purchaseGoodsDao.insert(goods);
            if (status && !isJkyProduct) {
                channelMerchantService.purchaseSupplierGood(goods, o);
            }
            // 记录手动推送日志
            StringBuilder sb = new StringBuilder();
            sb.append(null == userName ? "系统" : userName);
            sb.append("推送订单商品: ");
            sb.append(o.getInfo().getProductInfo().getStoreName());
            sb.append(isJkyProduct ? "到吉客云" : " ");
            sb.append(msg);
            storeOrderStatusService.createLog(storeOrder.getId(), storeOrder.getOrderId(), Constants.ORDER_STATUS_CACHE_PUSH_ORDER, sb.toString());

            if (9 == storeOrder.getSource() && status && BooleanUtils.isFalse(o.getCheckStock()) && !isJkyProduct) {
                // 减库存
                log.info("--------------- 手动推送订单商品id: {},sourceSkuId:{},  扣除库存: {} ---------------", o.getProductId(), o.getInfo().getProductInfo().getAttrInfo().getSourceSkuId(), o.getInfo().getCartNum());
                storeProductService.subProductStock(o.getInfo().getProductInfo().getId(), o.getInfo().getCartNum());
                // 减AttValue库存
                storeProductAttrValueService.subProductStock(o.getInfo().getProductInfo().getId(), o.getInfo().getProductInfo().getAttrInfo().getSourceSkuId(), o.getInfo().getCartNum());
            }
        });
    }

    public void updateOrderInfo(StoreOrder storeOrder, BarCodeEnum barCode) {

        //获取对应的子订单
        List<StoreOrderInfoVo> orderInfoVoList = storeOrderInfoService.getOrderListByOrderId(storeOrder.getId());
        List<StoreOrderInfoVo> result = new ArrayList<>();

        if(orderInfoVoList.size()==0){
            log.info("--------------- 获取订单状态处理 无子订单数据:{} ---------------", storeOrder.getId());
        }else
        {
            log.info("--------------- 获取订单状态处理 有子订单数据一共:{} 条 ---------------", orderInfoVoList.size());
        }

        for (StoreOrderInfoVo info : orderInfoVoList) {
            String sourceBarCode = info.getInfo().getProductInfo().getBarCode();
            log.info("--------------- 获取订单状态处理 sourceBarCode:{} barCode {} ---------------", sourceBarCode,barCode.getCode().toString());
            if (info.getStatus() == 6 && sourceBarCode.startsWith(barCode.getCode().toString())) { //未确认的im订单
                result.add(info);
            }
        }

        //获取对应的子订单
        for (StoreOrderInfoVo info : result) {

            log.info("--------------- 获取订单状态处理 主订单号: {},子订单号:{} ---------------", info.getOrderInfoId(), info.getChildOrderNumber());
            PurchaseGoods purchaseGoods = purchaseGoodsService.getOne(Wrappers.lambdaQuery(PurchaseGoods.class)
                    .eq(PurchaseGoods::getStoreOrderInfoId, info.getId())
                    .eq(PurchaseGoods::getStatus, 6)
                    .eq(PurchaseGoods::getChannelType, info.getIsEurope())
                    .eq(PurchaseGoods::getPushStatus, 1));

            if (purchaseGoods != null) {
                CommonResult<Object> orderInfo = this.getStoreOrderService(barCode).getOrderInfo(purchaseGoods.getChannelOrderSn());
                if (orderInfo.getCode() == 200) {

                    List<String> collect = Stream.of("已发货", "已收货", "已完成", "已确认").collect(Collectors.toList());
                    if (collect.contains(orderInfo.getData().toString())) {

                        purchaseGoods.setStatus(OrderStatusEnum.NOT_SHIPPED.getCode());

                        //更新
                        boolean b = purchaseGoodsService.updateById(purchaseGoods);
                        if (b) {

                            StoreOrderInfo storeOrderInfo = storeOrderInfoService.getById(info.getId());
                            storeOrderInfo.setStatus(OrderStatusEnum.NOT_SHIPPED.getCode());
                            boolean c = storeOrderInfoService.updateById(storeOrderInfo);

                            if (c) {
                                String message = "接口获取订单状态 更新成已确认！";
                                //确认订单记录备注
                                storeOrderStatusService.createLog(storeOrderInfo.getOrderId(), storeOrderInfo.getChildOrderNumber(), Constants.ORDER_CONFIRM_SUCCESS, message);
                                //查询子订单是不是都已经待确认
                                boolean isAllConfirm = storeOrderService.isAllConfirm(storeOrder, OrderStatusEnum.CONFIRM.getCode());

                                //查询主订单状态
                                if (isAllConfirm && storeOrder.getStatus().equals(OrderStatusEnum.CONFIRM.getCode())) {
                                    storeOrder.setStatus(OrderStatusEnum.NOT_SHIPPED.getCode());
                                    storeOrderService.updateById(storeOrder);
                                    log.info("--------------- 更新主订单状态为待发货 主订单号 {} ---------------", info.getOrderInfoId());
                                }
                                log.info("--------------- 更新订单状态完成 主订单号 {},子订单号:{} ---------------", info.getOrderInfoId(), info.getChildOrderNumber());
                            }
                        }
                    }
                }
            } else {
                log.info("--------------- 获取订单状态处理 没有采购单 {},{} ---------------", info.getId(), info.getOrderInfoId());
            }
        }
        log.info("--------------- 获取订单状态处理 处理完成！ ---------------");
    }

}
